package org.teemor.demo.nio.channel;

import org.junit.Test;
import org.teemor.demo.nio.BaseTest;

import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @Description:
 * @author zhoulk
 * @date: 2020/2/21
 */
public class FileChannelDemo implements BaseTest {

    /**
     * RandomAccessFile
     * 此类的实例支持读取和写入随机访问文件。
     * 随机访问文件的行为类似于存储在文件系统中的大字节数组。
     * 隐式数组中有一种游标或索引，称为文件指针；
     * 输入操作从文件指针开始读取字节，然后使文件指针越过读取的字节。
     * 如果随机访问文件是在读/写模式下创建的，则输出操作也可用；
     * 输出操作从文件指针开始写入字节，然后将文件指针前进到写入的字节之后。
     * 写入超出隐含数组当前端的输出操作将导致该数组被扩展。
     * 可以通过{@code getFilePointer}方法读取文件指针，并通过{@code seek}设置文件指针
     * @throws Exception
     */

    @org.junit.Test
    public void baseTest() throws Exception {

        RandomAccessFile accessFile = new RandomAccessFile("E:\\logs\\ai-cmdc-ams.log","rw");
        FileChannel fileChannel = accessFile.getChannel();

        //分配48容量的缓冲区，单位bytes
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        int byteRead = fileChannel.read(byteBuffer);
        while (byteRead != -1) {
            syso("Read " + byteRead);
            byteBuffer.flip();
            System.out.println(new String(byteBuffer.array(),"UTF-8"));
            while (byteBuffer.hasRemaining()) {
                this.syso((char) byteBuffer.get());
            }
            byteBuffer.clear();
            byteBuffer.rewind();
            byteBuffer.compact();
            byteBuffer.mark();
            byteBuffer.reset();
            byteRead = fileChannel.read(byteBuffer);
        }
        fileChannel.close();
    }

    @Test
    public void transferTest() throws Exception {
        RandomAccessFile fromFile = new RandomAccessFile("E:\\logs\\ai-cmdc-ams.log","rw");
        FileChannel fromChannel = fromFile.getChannel();

        RandomAccessFile toFile = new RandomAccessFile("E:\\logs\\ai-cmdc-ams2.log","rw");
        FileChannel toChannel = toFile.getChannel();

        RandomAccessFile toFile2 = new RandomAccessFile("E:\\logs\\ai-cmdc-ams3.log","rw");
        FileChannel toChannel2 = toFile2.getChannel();

        fromChannel.transferTo(0, fromChannel.size(), toChannel);
        toChannel2.transferFrom(fromChannel,0, fromChannel.size());
    }
}
